//
//  NSObject+BuildUIElement.h
//  Test
//
//  Created by WUwei on 17/5/1.
//  Copyright © 2017年 WUwei. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class WKWebView;
@interface NSObject (BuildUIElement)

#pragma mark -
#pragma mark -------------------------------- build UI Element -------------------------------
#pragma mark -

- (UIButton *)ww_buildButton:(NSString *)title
                    fontSize:(NSInteger)fontSize
                  titleColor:(UIColor *)titleColor
                 normalImage:(NSString *)normalImage
                      target:(id)target
                    selector:(SEL)selector
                 toSuperView:(UIView *)superView;

- (UIButton *)ww_buildImageButtonWithNormalImage:(NSString *)normalImage
                                   selectedImage:(NSString *)selectedImage
                                          target:(id)target
                                        selector:(SEL)selector
                                     toSuperView:(UIView *)superView;


- (UIButton *)ww_buildTitleButton:(NSString *)title
                            color:(UIColor *)color
                         fontSize:(NSInteger )fontSize
                           target:(id)target
                         selector:(SEL)selector
                      toSuperView:(UIView *)superView;


- (UILabel *)ww_buildLabel:(NSString *)text
                  fontSize:(NSInteger)fontSize
                     color:(UIColor *)color
                   bgColor:(UIColor *)bgColor
                 alignment:(NSTextAlignment)alignment
                     lines:(NSInteger)lines
               toSuperView:(UIView *)superView;

- (UIImageView *)ww_buildImageViewWithImage:(NSString *)image
                                contentMode:(UIViewContentMode)contentMode
                                toSuperView:(UIView *)superView;

- (UITextField *)ww_buildTextField:(NSString *)content
                 fontSize:(NSInteger )fontSize
                textColor:(UIColor *)textColor
                 delegate:(id)delegate
                 leftView:(UIView *)leftView
              toSuperView:(UIView *)superView;


- (UITextView *)ww_buildTextView:(NSString *)content
                fontSize:(NSInteger )fontSize
               textColor:(UIColor *)textColor
                 bgColor:(UIColor *)bgColor
                delegate:(id)delegate
      inputAccessoryView:(UIView *)inputAccessoryView
           returnKeyType:(UIReturnKeyType)returnKeyType
            contentInset:(UIEdgeInsets)contentInset
             toSuperView:(UIView *)superView;


- (UIScrollView *)ww_buildScrollView:(id)delegate
              contentWidth:(CGFloat)contentWidth
             contentHeight:(CGFloat)contentHeight
             pagingEnabled:(BOOL)pagingEnabled
                   bounces:(BOOL)bounces
         verticalIndicator:(BOOL)verticalIndicator
          horizonIndicator:(BOOL)horizonIndicator
               toSuperView:(UIView *)superView;


- (UITableView *)ww_buildTableViewWithStyle:(UITableViewStyle)style
                                   delegate:(id)delegate
                            scrollIndicator:(BOOL)scrollIndicator
                                toSuperView:(UIView *)superView
                             estimateHeight:(BOOL)estimateHeight
                                  rowHeight:(CGFloat)rowHeight
                        zeroMarginSeparator:(BOOL)zeroMarginSeparator
                                cellClasses:(Class)cellClass, ... NS_REQUIRES_NIL_TERMINATION;

- (UICollectionView *)ww_buildCollectionViewWithDelegate:(id)delegate
                                               itemWidth:(CGFloat)width
                                              itemHeight:(CGFloat)itemHeight
                                        InteritemSpacing:(CGFloat)InteritemSpacing
                                             lineSpacing:(CGFloat)lineSpacing
                                              headerSize:(CGSize)headerSize footerSize:(CGSize)footerSize
                                               direction:(UICollectionViewScrollDirection)direction
                                    showsScrollIndicator:(BOOL)showsScrollIndicator
                                             toSuperView:(UIView *)superView
                                             cellClasses:(Class)cellClass, ... NS_REQUIRES_NIL_TERMINATION ;


- (UICollectionView *)ww_buildCollectionViewWithLayout:(UICollectionViewLayout *)layout
                                           toSuperView:(UIView *)superView
                                              delegate:(id)delegate
                                           cellClasses:(Class)cellClass, ... NS_REQUIRES_NIL_TERMINATION;


- (UINavigationController *)ww_buildTabAndNaviVCWithVC:(UIViewController *)VC
                                             normalImg:(NSString *)normalImg
                                           selectedImg:(NSString *)selectedImg
                                                 title:(NSString *)title;

- (UISearchBar *)ww_buildSearchBarWithPlaceholder:(NSString *)placeholder
                                           height:(CGFloat)height
                                     innerBgColor:(UIColor *)innerBgColor
                               outterWrappedColor:(UIColor *)outterWrappedColor
                                         fontSize:(NSInteger )fontSize
                                        textColor:(UIColor *)textColor
                                      borderColor:(UIColor *)borderColor
                                      borderWidth:(NSInteger)borderWidth
                                      filterImage:(NSString *)filterImage
                                         delegate:(id)delegate
                                     cornerRadius:(CGFloat)cornerRadius
                                      cursorColor:(UIColor *)cursorColor
                                      toSuperView:(UIView *)superView;


- (WKWebView *)ww_buildWKWebViewWithDelegate:(id)delegate
                                 minFontSize:(NSInteger )minFontSize
                                 toSuperView:(UIView *)superView
                                  jsMessages:(NSString *)jsMessages, ... NS_REQUIRES_NIL_TERMINATION;


- (void)ww_addObserveNotificationWithSelector:(SEL)selector
                                        names:(NSString *)names, ... NS_REQUIRES_NIL_TERMINATION;


- (void)ww_buildViewWithBgColor:(UIColor *)bgColor
                    toSuperView:(UIView *)superView;


- (void)ww_roundTheView:(UIView *)view
                 radius:(NSInteger )radius
            borderWidth:(CGFloat)borderWidth
            borderColor:(UIColor *)borderColor;

- (void)ww_activeTheView:(UIView *)view
                  target:(id)target
                selector:(SEL)selector;

#pragma mark -
#pragma mark -------------------------------- string -------------------------------
#pragma mark -

- (NSMutableAttributedString *)ww_buildAttributedString:(NSString *)string
                                            lineSpacing:(CGFloat)lineSpacing
                                                   font:(UIFont *)font
                                                  color:(UIColor *)color;


NSString *ww_clockTimeWithDuration(long time);



#pragma mark -
#pragma mark -------------------------------- color -------------------------------
#pragma mark -


UIColor *ww_colorWithHexString(NSString *stringHex);

UIColor *ww_randomColor();

UIColor *ww_colorWithRGB(NSInteger r, NSInteger g, NSInteger b);

UIColor *ww_colorWithRGBA(NSInteger r, NSInteger g, NSInteger b, NSInteger a);

UIImage* ww_imageWithColor(UIColor* color, CGFloat height);

#pragma mark -
#pragma mark -------------------------------- otherTools -------------------------------
#pragma mark -

// 跳转到APP自己的设置：
void ww_gotoAppSetting();
// 判断是否安装了某个APP, urlString 的格式@"wei://wer.yt4.we":
BOOL ww_hasApp(NSString *urlString);
// 打开某个APP:
void ww_gotoApp(NSString *urlString);
// 显示/隐藏 状态栏:
void ww_hideStatusBar(BOOL hidden);

// 显示/隐藏 网络请求菊花:
void ww_showNetworkIndicator(BOOL show);

//- (void)ww_showNaviBar:(BOOL)show;

// 判断系统版本
CGFloat ww_version();

BOOL ww_iOS7();
BOOL ww_iOS8();
BOOL ww_iOS9();
BOOL ww_preiOS7();
BOOL ww_preiOS8();
BOOL ww_preiOS9();
BOOL ww_afteriOS7();
BOOL ww_afteriOS8();
BOOL ww_afteriOS9();
BOOL ww_ipad();
BOOL ww_iphone();
BOOL ww_ipod();
BOOL ww_iPhone5SE();
BOOL ww_iPhone6_6s();
BOOL ww_iPhone6Plus_6sPlus();


// 判断是否有摄像头权限:
BOOL ww_cameraAccessible();
// 获取 APP版本号
BOOL ww_appVersion();

// 获取 APP build version
NSString* ww_buildVersion();

// 获取 APP名称
NSString* ww_appName();

NSInteger ww_screenWidth();

NSInteger ww_screenHeight();
// temp 路径:
NSString * ww_pathTemp();
// Document 路径:
NSString * ww_pathDocument();
// Cache 路径
NSString * ww_pathCache();

// alert 弹框
void ww_showAlert(NSString *title, NSString *msg);


// 清空 某个 View 的所有子 view
void ww_removeSubviews(UIView *view);
// 开始设备自动锁屏
void ww_unLockScreen();
void ww_lockScreen();
// 如果文件夹不存在，创建该文件夹
void ww_createFolderIfNotExsit(NSString *folderPath);

// 如果存在某文件，就删除该文件:
void ww_deleteFileIfExists(NSString *filePath);

// APP主窗口  APP主导航控制器
UIWindow* ww_glWindow();

UIViewController *ww_rootVC();
NSUserDefaults * ww_ww_glUserDefaults();
NSNotificationCenter* ww_glNotificationCenter();
// 判断当前语言
NSString* ww_glLanguage();

UIFont* ww_font(NSInteger size);

UIFont* ww_fontBold(NSInteger size);

UIFont* ww_fontWithName(NSString *fontName, NSInteger fontSize);

NSURL* ww_url(NSString *urlString);

NSURL* ww_fileUrl(NSString *path);

UIImage* ww_image(NSString *imageName);

NSString* ww_bundlePath(NSString* name, NSString* type);

void ww_configBrightness(CGFloat brightness);
// 屏幕亮度相关:
CGFloat ww_brightness();

// 对url进行百分号编码
NSString * ww_urlEncode(NSString *stringUrl);

// 跳转到产品详情界面(跳转到appStore 应用) example:__gotoAppStore_descPage(444934666)
void ww_gotoAppStore_descPage(NSInteger productId);

// 跳转到产品评论界面(跳转到appStore 应用) example: __gotoAppStore_commentPage(444934666)
void ww_gotoAppStore_commentPage(NSInteger productId);

// 去除 字符串首尾空格和换行符
NSString * ww_stringCropBlank(NSString *string);

// 裁切图片
UIImage * ww_stretchImg(UIImage *image);

// 加载本地文件
UIImage * ww_imageFromFile(NSString *file, NSString *type);
NSArray* ww_arrayFromFile(NSString *file, NSString *type);

NSDictionary* ww_dicFromFile(NSString *file, NSString *type);

NSString * ww_stringConcat(NSString *str1, NSString *str2);

// 是否是视网膜屏幕
BOOL ww_retina();


typedef enum : NSUInteger {
    WWEventType_className_eventName,
} WWEventType;

typedef void (^WWEventCallBack)(BOOL success, id userInfo);
typedef void (^WWEventBlock)(id *from, WWEventType eventType, id userInfo, WWEventCallBack callback);

// block 类型 -常用
typedef void (^bk_v_v)();
typedef void (^bk_v_id)(id obj);
typedef void (^bk_v_id_id)(id obj1, id obj2);
typedef void (^bk_v_b)(BOOL isTrue);
typedef void (^bk_v_i)(NSInteger i_num);
typedef void (^bk_v_ui)(NSUInteger i_num);
typedef void (^bk_v_f)(CGFloat f_num);
typedef void (^bk_v_l)(long l_num);

// block 类型 -不常用
typedef BOOL (^bk_b_v)();
typedef BOOL (^bk_b_id)(id obj);
typedef BOOL (^bk_b_id_id)(id obj1, id obj2);
typedef BOOL (^bk_b_b)(BOOL isTrue);
typedef BOOL (^bk_b_i)(NSInteger i_num);
typedef BOOL (^bk_b_ui)(NSUInteger i_num);
typedef BOOL (^bk_b_f)(CGFloat f_num);
typedef BOOL (^bk_b_l)(long l_num);


typedef id (^bk_id_v)();
typedef id (^bk_id_id)(id obj);
typedef id (^bk_id_id_id)(id obj1, id obj2);
typedef id (^bk_id_b)(BOOL isTrue);
typedef id (^bk_id_i)(NSInteger i_num);
typedef id (^bk_id_ui)(NSUInteger i_num);
typedef id (^bk_id_f)(CGFloat f_num);
typedef id (^bk_id_l)(long l_num);


typedef NSInteger (^bk_i_v)();
typedef NSInteger (^bk_i_id)(id obj);
typedef NSInteger (^bk_i_id_id)(id obj1, id obj2);
typedef NSInteger (^bk_i_b)(BOOL isTrue);
typedef NSInteger (^bk_i_i)(NSInteger i_num);
typedef NSInteger (^bk_i_ui)(NSUInteger i_num);
typedef NSInteger (^bk_i_f)(CGFloat f_num);
typedef NSInteger (^bk_i_l)(long l_num);


typedef CGFloat (^bk_f_v)();
typedef CGFloat (^bk_f_id)(id obj);
typedef CGFloat (^bk_f_id_id)(id obj1, id obj2);
typedef CGFloat (^bk_f_b)(BOOL isTrue);
typedef CGFloat (^bk_f_i)(NSInteger i_num);
typedef CGFloat (^bk_f_ui)(NSUInteger i_num);
typedef CGFloat (^bk_f_f)(CGFloat f_num);
typedef CGFloat (^bk_f_l)(long l_num);

typedef long (^bk_l_v)();
typedef long (^bk_l_id)(id obj);
typedef long (^bk_l_id_id)(id obj1, id obj2);
typedef long (^bk_l_b)(BOOL isTrue);
typedef long (^bk_l_i)(NSInteger i_num);
typedef long (^bk_l_ui)(NSUInteger i_num);
typedef long (^bk_l_f)(CGFloat f_num);
typedef long (^bk_l_l)(long l_num);





#pragma mark -
#pragma mark -------------------------------- #define -------------------------------
#pragma mark -


//角度~弧度
#define degreesToRadian(x) (M_PI * (x) / 180.0)
#define radianToDegrees(radian) (radian*180.0)/(M_PI)

// 获取相机权限状态（一般是直接用下面两个 拒绝或同意）
#define SXCameraStatus [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]
#define SXCameraDenied ((SXCameraStatus == AVAuthorizationStatusRestricted)||(SXCameraStatus == AVAuthorizationStatusDenied))
#define SXCameraAllowed (!SXCameraDenyed)

// 定位权限
#define SXLocationStatus [CLLocationManager authorizationStatus];
#define SXLocationAllowed ([CLLocationManager locationServicesEnabled] && !((status == kCLAuthorizationStatusDenied) || (status == kCLAuthorizationStatusRestricted)))
#define SXLocationDenied (!SXLocationAllowed)

// 消息推送权限
#define SXPushClose (([[UIDevice currentDevice].systemVersion floatValue]>=8.0f)?(UIUserNotificationTypeNone == [[UIApplication sharedApplication] currentUserNotificationSettings].types):(UIRemoteNotificationTypeNone == [[UIApplication sharedApplication] enabledRemoteNotificationTypes]))
#define SXPushOpen (!SXPushClose)

#define MTBStretchImgCustom(image,w,h) [(image) stretchableImageWithLeftCapWidth:(image.size.width*(w)) topCapHeight:image.size.height*(h)]?:[UIImage new]


// 导航栏高度
#define kNaviBar_HEIGHT 44

// 状态栏高度
#define kStatusBarHeight        (20.f)
#define kStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height

#define kTopBarHeight           (44.f)
#define kTopBarWithStatusHeight (64.f)
#define kBottomBarHeight        (49.f)
#define kCellDefaultHeight      (44.f)
#define kEnglishKeyboardHeight  (216.f)
#define kChineseKeyboardHeight  (252.f)


//检查系统版本
#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)


#define GCD_GLOBAL(block)  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block)
#define GCD_MAIN(block)  dispatch_async(dispatch_get_main_queue(), block)

#define __textViewjudge UITextRange *selectedRange = [textView markedTextRange];\
UITextPosition *pos = [textView positionFromPosition:selectedRange.start offset:0];\
if (selectedRange && pos) {\
return;\
}\

// 弱引用/强引用
#define kWEWself(type)  __weak typeof(type) weak##type = type;
#define kWESself(type)  __strong typeof(type) type = weak##type;
// 设置 view 圆角和边框
#define kWEViewBorderRadius(View, Radius, Width, Color)\
\
[View.layer setCornerRadius:(Radius)];\
[View.layer setMasksToBounds:YES];\
[View.layer setBorderWidth:(Width)];\
[View.layer setBorderColor:[Color CGColor]]



// one pixel line
#define SINGLE_LINE_WIDTH           (1 / [UIScreen mainScreen].scale)
#define SINGLE_LINE_ADJUST_OFFSET   ((1 / [UIScreen mainScreen].scale) / 2)



// 非空block，把block和参数都写好，如果block不为空才执行
#define SXNotNilBlock(block, ...) if (block) { block(__VA_ARGS__); };



// 自动归档、解归档，description,使用方法：1.在.h文件里<NSCoding>  2..m文件里#import <objc/message.h>   3.在@implementation与@end之间插入此宏
#define __autoCodec \
+ (NSArray *)propertyOfSelf{\
unsigned int count = 0;\
Ivar *ivarList = class_copyIvarList(self, &count);\
NSMutableArray *properNames =[NSMutableArray array];\
for (int i = 0; i < count; i++) {\
Ivar ivar = ivarList[i];\
NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];\
NSString *key = [name substringFromIndex:1];\
[properNames addObject:key];\
}\
free(ivarList);\
return [properNames copy];\
}\
- (void)encodeWithCoder:(NSCoder *)enCoder{\
NSArray *properNames = [[self class] propertyOfSelf];\
for (NSString *propertyName in properNames) {\
[enCoder encodeObject:[self valueForKey:propertyName] forKey:propertyName];\
}\
}\
- (id)initWithCoder:(NSCoder *)aDecoder{\
NSArray *properNames = [[self class] propertyOfSelf];\
for (NSString *propertyName in properNames) {\
[self setValue:[aDecoder decodeObjectForKey:propertyName] forKey:propertyName];\
}\
return  self;\
}\
- (NSString *)description{\
NSMutableString *descriptionString = [NSMutableString stringWithFormat:@"\n<Address:%p , Class:%@>\n",self,[self class]];\
NSArray *properNames = [[self class] propertyOfSelf];\
for (NSString *propertyName in properNames) {\
NSString *propertyNameString = [NSString stringWithFormat:@"_%@ : %@\n",propertyName,[self valueForKey:propertyName]];\
[descriptionString appendString:propertyNameString];\
}\
return [descriptionString copy];\
}

// description,使用方法：1..m文件里#import <objc/message.h>   2.在@implementation与@end之间插入此宏
#define __autoDescription \
+ (NSArray *)propertyOfSelf{\
unsigned int count = 0;\
Ivar *ivarList = class_copyIvarList(self, &count);\
NSMutableArray *properNames =[NSMutableArray array];\
for (int i = 0; i < count; i++) {\
Ivar ivar = ivarList[i];\
NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];\
NSString *key = [name substringFromIndex:1];\
[properNames addObject:key];\
}\
free(ivarList);\
return [properNames copy];\
}\
- (NSString *)description{\
NSMutableString *descriptionString = [NSMutableString stringWithFormat:@"\n<Address:%p , Class:%@>\n",self,[self class]];\
NSArray *properNames = [[self class] propertyOfSelf];\
for (NSString *propertyName in properNames) {\
NSString *propertyNameString = [NSString stringWithFormat:@"_%@ : %@\n",propertyName,[self valueForKey:propertyName]];\
[descriptionString appendString:propertyNameString];\
}\
return [descriptionString copy];\
}

// 强引用 & 弱引用
#define ww_weakify(obj) __weak typeof(obj) weakObj = obj;
#define ww_strongify(obj) __block typeof(weakObj) obj = weakObj;


#define __deSelectWithAnimated(animate) [tableView deselectRowAtIndexPath:indexPath animated:animate];

// UITableView的Group样式下顶部空白处理
#define __removeTableViewHeaderspace(tableView) UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0.1)];\
tableView.tableHeaderView = view;

// 移除tableView中的横线
#define __removeTableViewFootLine(tableView) UIView *emptyFootView = [UIView new];\
tableView.tableFooterView = emptyFootView;

// App Info
#define WWW_APP_ID               @"961330940"
#define WWW_APP_STORE_URL        @"https://itunes.apple.com/cn/app/id"WWW_APP_ID"?mt=8"
#define WWW_APP_STORE_REVIEW_URL @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id="WWW_APP_ID@"&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software"



// 使获取 属性的 string  key 有代码提示
#define keypath(property) @getKeypathString(property)
#define getKeypathString(PATH) \
(((void)(NO && ((void)PATH, NO)), strchr(# PATH, '.') + 1))

// 销毁定时器
#define __destroyTimer(timer) [timer invalidate], timer = nil;



// 实现单例
#define __sharedInstance_h + (instancetype)sharedInstance; // 放在.h文件 @interface 与 @end 之间
#define __sharedInstance_m(className) \
static className *_instance = nil; \
+ (instancetype)sharedInstance { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone { \
return _instance; \
} // 放在.m 文件 @implementation 与 @end 之间

// 直接从对象获取类名字符串
#define className(object) NSStringFromClass([object class])



// 禁止使用第三方键盘
#define ___disable3dKeyboard \
- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier {\
if ([extensionPointIdentifier isEqualToString: UIApplicationKeyboardExtensionPointIdentifier]) {\
return NO;\
}\
return YES;\
}\
// 隐藏键盘(点击屏幕任意位置)
#define ___hideKeyboard \
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ \
[super touchesBegan:touches withEvent:event]; \
[self.view endEditing:YES]; \
}



//#define __showErrorAlert(message) \
//UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Error" \
//message:message \
//preferredStyle:UIAlertControllerStyleAlert]; \
//UIAlertAction *retryAction = [UIAlertAction actionWithTitle:@"确定" \
//style:UIAlertActionStyleDefault \
//handler:^(UIAlertAction *action) { \
//\
//}]; \
//[alertController addAction:retryAction]; \
//[self presentViewController:alertController animated:YES completion:nil];





@end
